using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;

namespace Gj
{
    public enum Point
    {
        Center,
        Top,
        Bottom
    }

    public enum Direction
    {
        Center,
        Top,
        Bottom,
        Left,
        Right,
    }

    public class PopupHelper : CompareHelper
    {
        public Color maskColor = new(0, 0, 0, 0.5f);
        public Direction direction = Direction.Center;
        public float waitTime = 0.5f;
        public AudioClip showClip;
        public SoundType showSoundType;
        public AudioClip hideClip;
        public SoundType hideSoundType;
        public iTween.EaseType easeType = iTween.EaseType.linear;

        public GameObject Container;
        public GameObject Parent;
        public bool full = false;
        public bool mask = true;
        public bool maskClose = true;
        public bool containerClose;
        public ScrollRect[] ScrollRects;
        private float _height;
        private float _width;
        private Vector3 hidePosition = Vector3.zero;
        [SerializeField]
        private bool isShow;
        private Vector3 showPosition = Vector3.zero;

        // Use this for initialization
        protected override void Start()
        {
            base.Start();
            if (!containerClose)
                UnityTools.GetComponentRequire<Button>(Container).transition = Selectable.Transition.None;
            isShow = false;
            Container.SetActive(true);
            gameObject.SetActive(false);
            if (_width == 0)
                RefreshWidthHeight(GetComponent<RectTransform>().rect.width,
                    GetComponent<RectTransform>().rect.height);
        }

        public override void Show()
        {
            SetChildData(_data);
            if (isShow) return;
            isShow = true;

            if (showSoundType != SoundType.None)
                Game.single.PlayEFF(showSoundType);
            else if (showClip != null) Game.single.PlayEFF(showClip);

            gameObject.SetActive(true);

            iTween.Stop(gameObject);

            if (direction == Direction.Center)
                Container.transform.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, 0);
            else
                Container.transform.localPosition = Vector3.Lerp(hidePosition, showPosition, 0);

            if (Parent != null)
            {
                transform.SetParent(null, false);
                transform.SetParent(Parent.transform, false);
            }

            if (Time.timeScale == 0)
            {
                if (mask) UnityTools.GetComponentRequire<Image>(gameObject).color = Color.clear;
                if (mask && maskClose) UnityTools.GetComponentRequire<Button>(gameObject).onClick.AddListener(Close);

                if (mask) gameObject.GetComponent<Image>().color = Color.Lerp(Color.clear, maskColor, 1);
                if (direction == Direction.Center)
                    Container.transform.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, 1);
                else
                    Container.transform.localPosition = Vector3.Lerp(hidePosition, showPosition, 1);
            }
            else
            {
                var ht = new Hashtable();
                ht.Add("from", 0.0f);
                ht.Add("to", 1.0f);
                ht.Add("time", waitTime * Time.timeScale);
                ht.Add("easetype", easeType);
                ht.Add("onstart", (Action<object>)(newVal =>
                {
                    if (direction == Direction.Center)
                    {
                        Container.transform.localScale = Vector3.zero;
                        for (var i = 0; i < ScrollRects.Length; i++) ScrollRects[i].enabled = false;
                    }

                    if (mask) UnityTools.GetComponentRequire<Image>(gameObject).color = Color.clear;
                    if (mask && maskClose) UnityTools.GetComponentRequire<Button>(gameObject).onClick.AddListener(Close);
                }));
                ht.Add("onupdate", (Action<object>)(newVal =>
                {
                    var v = (float)newVal;
                    if (mask) gameObject.GetComponent<Image>().color = Color.Lerp(Color.clear, maskColor, v);
                    if (direction == Direction.Center)
                        Container.transform.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, v);
                    else
                        Container.transform.localPosition = Vector3.Lerp(hidePosition, showPosition, v);
                }));
                ht.Add("oncomplete", (Action<object>)(newVal =>
                {
                    SetChildData(_data);
                    if (direction == Direction.Center)
                        for (var i = 0; i < ScrollRects.Length; i++)
                            ScrollRects[i].enabled = true;
                }));

                iTween.ValueTo(gameObject, ht);
            }
        }

        public override void Hide()
        {
            if (!isShow) return;
            isShow = false;

            if (hideSoundType != SoundType.None)
                Game.single.PlayEFF(hideSoundType);
            else if (hideClip != null) Game.single.PlayEFF(hideClip);

            if (Time.timeScale == 0)
            {
                if (mask) gameObject.GetComponent<Image>().color = Color.Lerp(maskColor, Color.clear, 1);
                if (direction == Direction.Center)
                    Container.transform.localScale = Vector3.Lerp(Vector3.one, Vector3.zero, 1);
                else
                    Container.transform.localPosition = Vector3.Lerp(showPosition, hidePosition, 1);
                gameObject.SetActive(false);
                Destroy(gameObject.GetComponent<Image>());
                if (mask && maskClose) Destroy(gameObject.GetComponent<Button>());
            }
            else
            {
                var ht = new Hashtable();
                ht.Add("from", 0.0f);
                ht.Add("to", 1.0f);
                ht.Add("time", waitTime * Time.timeScale);
                ht.Add("easetype", easeType);
                ht.Add("onstart", (Action<object>)(newVal =>
                {
                    if (direction == Direction.Center)
                        for (var i = 0; i < ScrollRects.Length; i++)
                            ScrollRects[i].enabled = false;
                }));
                ht.Add("onupdate", (Action<object>)(newVal =>
                {
                    var v = (float)newVal;
                    if (mask) gameObject.GetComponent<Image>().color = Color.Lerp(maskColor, Color.clear, v);
                    if (direction == Direction.Center)
                        Container.transform.localScale = Vector3.Lerp(Vector3.one, Vector3.zero, v);
                    else
                        Container.transform.localPosition = Vector3.Lerp(showPosition, hidePosition, v);
                }));
                ht.Add("oncomplete", (Action<object>)(newVal =>
                {
                    gameObject.SetActive(false);
                    Destroy(gameObject.GetComponent<Image>());
                    if (mask && maskClose) Destroy(gameObject.GetComponent<Button>());
                }));

                iTween.ValueTo(gameObject, ht);
            }
        }

        public void RefreshWidthHeight(float width, float height)
        {
            _width = width;
            _height = height;
            var rectTransform = Container.GetComponent<RectTransform>();
            if (direction == Direction.Top || direction == Direction.Bottom)
            {
                if (full) rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, width);
                var rh = rectTransform.rect.height / 2;
                var h = height / 2;
                if (direction == Direction.Top)
                {
                    hidePosition = new Vector3(0, h + rh, 0);
                    showPosition = new Vector3(0, h - rh, 0);
                }
                else if (direction == Direction.Bottom)
                {
                    hidePosition = new Vector3(0, (h + rh) * -1, 0);
                    showPosition = new Vector3(0, (h - rh) * -1, 0);
                }
            }
            if (direction == Direction.Left || direction == Direction.Right)
            {
                if (full) rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height);
                var rw = rectTransform.rect.width / 2;
                var w = width / 2;
                if (direction == Direction.Left)
                {
                    hidePosition = new Vector3((w + rw) * -1, 0, 0);
                    showPosition = new Vector3((w - rw) * -1, 0, 0); 
                }
                else if (direction == Direction.Right)
                {
                    hidePosition = new Vector3(w + rw, 0, 0);
                    showPosition = new Vector3(w - rw, 0, 0);
                }
            }

            if (!isShow) Container.transform.localPosition = hidePosition;
            if (isShow) Container.transform.localPosition = showPosition;
        }

        public void Close()
        {
            Emit(UIEvent.Close);
        }
    }
}